<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">
<link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
<link rel="import" href="../../bower_components/paper-toast/paper-toast.html">
<link rel="import" href="../../bower_components/paper-checkbox/paper-checkbox.html">
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
<link rel="import" href="../../bower_components/paper-input/paper-input-container.html">
<link rel="import" href="../../bower_components/paper-dialog-behavior/paper-dialog-behavior.html">
<link rel="import" href="../../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html">
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
<link rel="import" href="../../bower_components/iron-icons/iron-icons.html">
<link rel="import" href="../../bower_components/iron-icons/av-icons.html">
<link rel="import" href="shared-styles.html">
<link rel="import" href="tag-input.html">

<dom-module id="build-queue">
    <template>
        <style include="shared-styles"></style>
        <style is="custom-style">
            :host {
                display: block;
                width: 30%;
                text-align: center;
            }

            .item {
                display: flex;
                margin-top: 4px;
                margin-left: 6px;
                margin-right: 6px;
            }

            .title {
                text-align: left;
                display: block;
                margin-left: 12px;
            }

            .build {
                cursor: pointer;
                width: 100%;
                top: -18px;
            }

            #spinner {
                display: block;
                margin: auto;
                margin-top: 12px;
            }

            .configuration {
                font-size: 1.0em;
                margin-bottom: 4px;
                opacity: 0.85;
                display: flex;
                flex-direction: row-reverse;
                justify-content: space-between;
                transition: border-color 0.2s;
                border-style: groove;
                border-width: 1px;
                border-color: rgba(255, 255, 255, 0.2);
                box-sizing: border-box;
            }

            .configuration:hover {
                border-color: rgba(255, 255, 255, 0.4);
            }

            .branch {
                text-align: left;
                float: left;
                left: 61px;
                position: absolute;
            }

            .repository {
                text-align: left;
                position: absolute;
                right: 56px;
                width: 40%;
            }

            .description {
                padding-bottom: 12px;
            }

            .inputs {
                text-align: left;
            }

            paper-checkbox {
                margin: 0;
                padding-bottom: 14px;
                padding-top: 14px;
                box-sizing: border-box;
            }

            .dialog-content {
                min-height: 176px;
            }

            .new {
                margin-top: 12px;
                display: block;
            }

            .empty {
                opacity: var(--opacity);
                margin-bottom: 12px;
                display: block;
            }

            .icon-button {
                margin-top: 0px;
            }

            .scriptName {
                position: absolute;
                left: 61px;
            }

        </style>

        <span class="title">
            <h4>
                Build queue
                <template is="dom-if" if="[[!started]]">
                    <paper-spinner id="spinner" active></paper-spinner>
                </template>

                <template is="dom-if" if="{{_isQueueAvailable(started, authenticated)}}">
                    <iron-icon on-click="_start" class="build icon" icon="av:play-circle-outline"></iron-icon>
                </template>
            </h4>
        </span>

        <paper-dialog id="queue" with-backdrop>
            <h2>Queue</h2>
            <paper-dialog-scrollable>

                <div class="dialog-content">
                    <template is="dom-if" if="{{!_saveable(editing, creating)}}">
                        <div class="description">Select a configuration to schedule a build.</div>
                        <template is="dom-repeat" items="{{configurations}}" as="configuration">
                            <paper-item class="configuration">

                                <!-- only admins may edit configuration. -->
                                <template is="dom-if" if="{{_isAdmin(authenticated)}}">
                                    <iron-icon on-click="_edit" class="icon" icon="icons:settings"></iron-icon>
                                </template>

                                <template is="dom-if" if="{{_isCloneable(configuration)}}">
                                    <span class="branch">[[configuration.branch]]</span>
                                    <span class="repository">[[_trimRepo(configuration.repository)]]</span>
                                </template>

                                <template is="dom-if" if="{{!_isCloneable(configuration)}}">
                                    <span class="scriptName">{{_scriptName(configuration)}}</span>
                                </template>

                                <iron-icon on-click="_schedule" class="icon" icon="av:play-circle-outline"></iron-icon>
                            </paper-item>
                        </template>

                        <!-- only admins may create new build jobs. -->
                        <template is="dom-if" if="{{_isAdmin(authenticated)}}">
                            <a href="#" class="new" on-click="_new">new</a>
                        </template>
                    </template>

                    <template is="dom-if" if="{{_saveable(editing, creating)}}">
                        <div class="description">Edit or create a new build.</div>
                        <div class="inputs">

                            <!-- paper-input is broken; unable to set text color. use iron-input. -->
                            <paper-input-container>
                                <label slot="label">repository (url, or name for scripts.)</label>
                                <iron-input autofocus slot="input" bind-value="{{config.repository}}">
                                    <input autofocus>
                                </iron-input>
                            </paper-input-container>

                            <paper-input-container>
                                <label slot="label">branch (optional)</label>
                                <iron-input slot="input" bind-value="{{config.branch}}">
                                    <input>
                                </iron-input>
                            </paper-input-container>

                            <paper-input-container>
                                <label slot="label">commandline</label>
                                <iron-input slot="input" bind-value="{{config.cmdLine}}">
                                    <input>
                                </iron-input>
                            </paper-input-container>

                            <paper-input-container>
                                <label slot="label">docker image (optional)</label>
                                <iron-input slot="input" bind-value="{{config.dockerImage}}">
                                    <input>
                                </iron-input>
                            </paper-input-container>

                            <!-- enable this when artifact download is implemented. -->
                            <!--<tag-input label="output directories" value="{{tagtext}}" values="{{config.outputDirs}}"></tag-input>-->
                        </div>
                        <paper-checkbox style="text-align: center;" checked="{{config.autoclean}}" class="picker">Auto
                            cleanup
                        </paper-checkbox>
                        <!-- prevents the contents from overflowing and showing the scrollbar when the checkbox is ticked -->
                        <hr style="visibility: hidden;">
                    </template>

                </div>

            </paper-dialog-scrollable>

            <template is="dom-if" if="{{editing}}">
                <iron-icon on-click="_delete" class="icon-button icon" icon="icons:clear"></iron-icon>
            </template>

            <template is="dom-if" if="{{_saveable(editing, creating)}}">
                <iron-icon on-click="_save" class="icon-button icon" icon="icons:check"></iron-icon>
            </template>

            <div class="buttons">
                <paper-button raised dialog-dismiss>Close</paper-button>
            </div>
        </paper-dialog>

        <span class="empty">{{_queued(builds)}}</span>

        <template is="dom-repeat" items="[[builds]]" as="build">
            <build-card build="[[build]]"></build-card>
        </template>

        <paper-toast id="toast" text="[[errorText]]"></paper-toast>

        <iron-ajax id="configurationLoader" method="POST" url="/api/" handle-as="json" on-response="_onConfiguration"></iron-ajax>
        <iron-ajax id="buildScheduler" method="POST" url="/api/" handle-as="json" on-response="_onQueued"></iron-ajax>
        <iron-ajax id="loadQueue" method="POST" url="/api/" handle-as="json" on-response="_onBuilds" auto></iron-ajax>
        <iron-ajax id="updateConfig" method="POST"  url="/api/" handle-as="json" on-response="_onUpdated" content-type="application/json"></iron-ajax>
        <iron-ajax id="deleteConfig" method="POST" url="/api/" handle-as="json" on-response="_onDelete"></iron-ajax>
    </template>
</dom-module>
<script>
    class BuildQueue extends Polymer.Element {

        static get is() {
            return 'build-queue';
        }

        constructor() {
            super();
            this.builds = [];
            this.started = false;
            this.editing = false;
            this.creating = false;
            this.authenticated = false;

            application.onLogout(() => {
                this.authenticated = false;
            });

            application.subscribe('schedule', (configId) => {
                for (let config of this.configurations) {
                    if (config.id === configId) {
                        this._schedule({model: {configuration: config}});
                    }
                }
            });
        }

        ready() {
            super.ready();
            setInterval(() => {
                this._loadQueue();
            }, 2500);
            this._loadQueue();

            application.onAuthenticated(() => {
                this.authenticated = true;
                this._reload();
            });
        }

        _queued(builds) {
            if (builds.length === 0) {
                return "empty";
            } else {
                return builds.length + " in queue"
            }
        }

        _loadQueue() {
            this.$.loadQueue.body = JSON.stringify({
                token: application.token,
                target: 'builds',
                route: 'queued'
            });
            this.$.loadQueue.generateRequest();
        }

        _onBuilds(event, request) {
            this.started = true;
            if (request.response.list) {
                this.set('builds', request.response.list);
            }
        }

        _isCloneable(configuration) {
            return configuration.branch !== "";
        }

        _scriptName(configuration) {
            if (configuration.repository) {
                return configuration.repository;
            } else {
                return (configuration.cmdLine.substring(0, Math.min(48, configuration.cmdLine.length)));
            }
        }

        _isQueueAvailable() {
            return this.started && this.authenticated;
        }

        _isAdmin() {
            return application.role('admin');
        }

        _saveable(editing, creating) {
            return (editing | creating);
        }

        _isEmpty(builds) {
            return builds.length === 0;
        }

        _start() {
            this.editing = false;
            this.creating = false;
            this.$.configurationLoader.generateRequest();
            this.$.queue.open();
        }

        _edit(e) {
            this.config = e.model.configuration;
            this.branch = this.config.branch;
            this.repository = this.config.repository;
            this.id = this.config.id;
            this.editing = true;
        }

        _delete() {
            this.$.deleteConfig.body = JSON.stringify({
                token: application.token,
                id: this.id,
                target: 'config',
                route: 'remove'
            });
            this.$.deleteConfig.generateRequest();
        }

        _onDelete() {
            this._reload();
        }

        _onUpdated(event, request) {
            let response = request.response;
            if (response.status === 'ERROR') {
                this.errorText = response.message;
                this.$.toast.open();
            } else {
                this._reload();
            }
        }

        _reload() {
            this.editing = false;
            this.creating = false;

            this.$.configurationLoader.body = JSON.stringify({
                token: application.token,
                target: 'config',
                route: 'list'
            });

            this.$.configurationLoader.generateRequest();
        }

        _save() {
            this.$.updateConfig.body = {
                    token: application.token,
                    config: this.config,
                    route: 'add',
                    target: 'config'
                };
            this.$.updateConfig.generateRequest();
        }

        _new() {
            this.creating = true;
            this.config = {'outputDirs': []};
        }

        _trimScript(string) {
            return string.substring(0, Math.min(64, string.length));
        }

        _trimRepo(string) {
            if (string && string.indexOf('/') > -1) {
                let parts = string.split('/');
                return parts[parts.length - 1];
            } else {
                return string;
            }
        }

        _schedule(e) {
            let config = e.model.configuration;
            this.branch = config.branch;
            this.repository = config.repository;
            this.id = config.id;

            this.$.buildScheduler.body = JSON.stringify({
                token: application.token,
                id: this.id,
                target: 'builds',
                route: 'submit'
            });

            this.$.buildScheduler.generateRequest();
            this.$.queue.close();
        }

        _onQueued(event, request) {
            this.builds.push(request.response);
            let builds = this.builds;
            this.set('builds', []);
            this.set('builds', builds);
        }

        _onConfiguration(event, request) {
            console.log('got config response = ' + request.response.status);
            if (request.response.collection) {
                console.log('got config for reals');
                this.configurations = request.response.collection;
                this.set('configurations', request.response.collection);
                this.notifySplices('configurations');
                this.notifyPath('configurations');
            }
        }
    }

    window.customElements.define(BuildQueue.is, BuildQueue);



</script>